/**
 * 统计服务
 * 提供数据统计、成就、等级、排行榜等功能
 */
import { BaseService } from './base.service';
import type {
  StatisticsData,
  EfficiencyAnalysis,
  QualityTrendData,
  Achievement,
  UserLevel,
  CalendarData,
  RankingsData,
  TimeRange,
  RankingType,
  CreationGoal,
  StatisticsReport,
  EventTracking,
} from '@/types/statistics';

const API_BASE_URL = import.meta.env.VITE_API_URL || '/api/v1';

class StatisticsService extends BaseService {
  private baseUrl = `${API_BASE_URL}/statistics`;

  /**
   * 获取创作数据统计
   * @param timeRange 时间范围
   */
  async getStatistics(timeRange: TimeRange = 'all'): Promise<StatisticsData> {
    try {
      return await this.get<StatisticsData>(`${this.baseUrl}/overview`, { timeRange });
    } catch (error) {
      console.error('Failed to get statistics:', error);
      // 返回模拟数据作为降级方案
      return this.getMockStatistics(timeRange);
    }
  }

  /**
   * 获取创作效率分析
   * @param timeRange 时间范围
   */
  async getEfficiencyAnalysis(timeRange: TimeRange = 'month'): Promise<EfficiencyAnalysis> {
    try {
      return await this.get<EfficiencyAnalysis>(`${this.baseUrl}/efficiency`, { timeRange });
    } catch (error) {
      console.error('Failed to get efficiency analysis:', error);
      return this.getMockEfficiencyAnalysis();
    }
  }

  /**
   * 获取质量进步追踪数据
   * @param timeRange 时间范围
   */
  async getQualityTrend(timeRange: TimeRange = 'month'): Promise<QualityTrendData[]> {
    try {
      return await this.get<QualityTrendData[]>(`${this.baseUrl}/quality-trend`, { timeRange });
    } catch (error) {
      console.error('Failed to get quality trend:', error);
      return this.getMockQualityTrend();
    }
  }

  /**
   * 获取用户成就列表
   */
  async getAchievements(): Promise<Achievement[]> {
    try {
      return await this.get<Achievement[]>(`${this.baseUrl}/achievements`);
    } catch (error) {
      console.error('Failed to get achievements:', error);
      return this.getMockAchievements();
    }
  }

  /**
   * 解锁成就
   * @param achievementId 成就ID
   */
  async unlockAchievement(achievementId: string): Promise<Achievement> {
    try {
      return await this.post<Achievement>(`${this.baseUrl}/achievements/${achievementId}/unlock`);
    } catch (error) {
      console.error('Failed to unlock achievement:', error);
      throw error;
    }
  }

  /**
   * 获取用户等级和经验
   */
  async getUserLevel(): Promise<UserLevel> {
    try {
      return await this.get<UserLevel>(`${this.baseUrl}/level`);
    } catch (error) {
      console.error('Failed to get user level:', error);
      return this.getMockUserLevel();
    }
  }

  /**
   * 增加经验值
   * @param xp 经验值
   * @param source 来源
   */
  async addExperience(xp: number, source: string): Promise<UserLevel> {
    try {
      return await this.post<UserLevel>(`${this.baseUrl}/level/add-xp`, { xp, source });
    } catch (error) {
      console.error('Failed to add experience:', error);
      throw error;
    }
  }

  /**
   * 获取创作日历数据
   * @param year 年份
   * @param month 月份 (1-12)
   */
  async getCreationCalendar(year: number, month?: number): Promise<CalendarData> {
    try {
      const params: any = { year };
      if (month !== undefined) {
        params.month = month;
      }
      return await this.get<CalendarData>(`${this.baseUrl}/calendar`, params);
    } catch (error) {
      console.error('Failed to get creation calendar:', error);
      return this.getMockCalendarData(year, month);
    }
  }

  /**
   * 获取排行榜数据
   * @param type 排行榜类型
   * @param timeRange 时间范围
   * @param limit 返回数量限制
   */
  async getRankings(
    type: RankingType = 'words',
    timeRange: TimeRange = 'month',
    limit: number = 100
  ): Promise<RankingsData> {
    try {
      return await this.get<RankingsData>(`${this.baseUrl}/rankings`, {
        type,
        timeRange,
        limit,
      });
    } catch (error) {
      console.error('Failed to get rankings:', error);
      return this.getMockRankings(type);
    }
  }

  /**
   * 获取创作目标
   */
  async getCreationGoals(): Promise<CreationGoal[]> {
    try {
      return await this.get<CreationGoal[]>(`${this.baseUrl}/goals`);
    } catch (error) {
      console.error('Failed to get creation goals:', error);
      return this.getMockGoals();
    }
  }

  /**
   * 创建创作目标
   * @param goal 目标数据
   */
  async createGoal(
    goal: Omit<CreationGoal, 'id' | 'current' | 'completed'>
  ): Promise<CreationGoal> {
    try {
      return await this.post<CreationGoal>(`${this.baseUrl}/goals`, goal);
    } catch (error) {
      console.error('Failed to create goal:', error);
      throw error;
    }
  }

  /**
   * 更新目标进度
   * @param goalId 目标ID
   * @param current 当前进度
   */
  async updateGoalProgress(goalId: string, current: number): Promise<CreationGoal> {
    try {
      return await this.patch<CreationGoal>(`${this.baseUrl}/goals/${goalId}`, { current });
    } catch (error) {
      console.error('Failed to update goal progress:', error);
      throw error;
    }
  }

  /**
   * 删除目标
   * @param goalId 目标ID
   */
  async deleteGoal(goalId: string): Promise<void> {
    try {
      await this.delete(`${this.baseUrl}/goals/${goalId}`);
    } catch (error) {
      console.error('Failed to delete goal:', error);
      throw error;
    }
  }

  /**
   * 生成统计报告
   * @param format 报告格式 (pdf | excel)
   * @param timeRange 时间范围
   */
  async generateReport(
    format: 'pdf' | 'excel',
    timeRange: TimeRange = 'month'
  ): Promise<Blob> {
    try {
      const response = await fetch(
        `${this.baseUrl}/report${this.buildQueryString({ format, timeRange })}`,
        {
          method: 'GET',
          headers: this.getHeaders(),
        }
      );

      if (!response.ok) {
        throw new Error('Failed to generate report');
      }

      return await response.blob();
    } catch (error) {
      console.error('Failed to generate report:', error);
      throw error;
    }
  }

  /**
   * 下载报告
   * @param format 报告格式
   * @param timeRange 时间范围
   */
  async downloadReport(format: 'pdf' | 'excel', timeRange: TimeRange = 'month'): Promise<void> {
    try {
      const blob = await this.generateReport(format, timeRange);
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `statistics-report-${timeRange}.${format}`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      window.URL.revokeObjectURL(url);
    } catch (error) {
      console.error('Failed to download report:', error);
      throw error;
    }
  }

  /**
   * 获取统计报告摘要
   * @param timeRange 时间范围
   */
  async getStatisticsReport(timeRange: TimeRange = 'month'): Promise<StatisticsReport> {
    try {
      return await this.get<StatisticsReport>(`${this.baseUrl}/report/summary`, { timeRange });
    } catch (error) {
      console.error('Failed to get statistics report:', error);
      return this.getMockStatisticsReport(timeRange);
    }
  }

  /**
   * 记录事件
   * @param event 事件名称
   * @param metadata 事件元数据
   */
  async trackEvent(event: string, metadata?: Record<string, any>): Promise<void> {
    try {
      const tracking: EventTracking = {
        event,
        metadata,
        timestamp: new Date().toISOString(),
      };
      await this.post(`${this.baseUrl}/events`, tracking);
    } catch (error) {
      console.error('Failed to track event:', error);
      // 不抛出错误，避免影响用户体验
    }
  }

  // ========== Mock数据方法 (降级方案) ==========

  private getMockStatistics(timeRange: TimeRange): StatisticsData {
    const baseData = {
      totalWords: 125000,
      totalArticles: 48,
      totalDays: 90,
      consecutiveDays: 7,
      avgQualityScore: 85.5,
      aiUsageCount: 156,
      templateUsageCount: 32,
      inspirationCount: 89,
    };

    // 根据时间范围调整数据
    const multiplier = timeRange === 'today' ? 0.01 : timeRange === 'week' ? 0.1 : timeRange === 'month' ? 0.3 : 1;

    return {
      totalWords: Math.floor(baseData.totalWords * multiplier),
      totalArticles: Math.floor(baseData.totalArticles * multiplier),
      totalDays: timeRange === 'today' ? 1 : timeRange === 'week' ? 7 : timeRange === 'month' ? 30 : baseData.totalDays,
      consecutiveDays: baseData.consecutiveDays,
      avgQualityScore: baseData.avgQualityScore,
      aiUsageCount: Math.floor(baseData.aiUsageCount * multiplier),
      templateUsageCount: Math.floor(baseData.templateUsageCount * multiplier),
      inspirationCount: Math.floor(baseData.inspirationCount * multiplier),
    };
  }

  private getMockEfficiencyAnalysis(): EfficiencyAnalysis {
    return {
      avgTimePerArticle: 125,
      stageBreakdown: {
        brainstorm: 25,
        outline: 20,
        writing: 80,
        optimization: 15,
      },
      peakHours: [9, 10, 14, 15, 20, 21],
      efficiencyTrend: this.generateMockTrendData(30, 60, 120),
    };
  }

  private getMockQualityTrend(): QualityTrendData[] {
    const days = 30;
    const trend: QualityTrendData[] = [];
    const today = new Date();

    for (let i = days - 1; i >= 0; i--) {
      const date = new Date(today);
      date.setDate(date.getDate() - i);

      const baseScore = 70 + Math.random() * 20;
      trend.push({
        date: date.toISOString().split('T')[0],
        score: Math.round(baseScore),
        breakdown: {
          structure: Math.round(baseScore + Math.random() * 10 - 5),
          logic: Math.round(baseScore + Math.random() * 10 - 5),
          readability: Math.round(baseScore + Math.random() * 10 - 5),
          originality: Math.round(baseScore + Math.random() * 10 - 5),
        },
      });
    }

    return trend;
  }

  private getMockAchievements(): Achievement[] {
    return [
      {
        id: 'ach_first_article',
        name: '初次尝试',
        description: '完成第一篇文章',
        icon: '🎉',
        category: 'beginner',
        unlocked: true,
        unlockedAt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
        rewards: { xp: 100, badge: '新手作者' },
      },
      {
        id: 'ach_10_articles',
        name: '初露锋芒',
        description: '累计完成10篇文章',
        icon: '📝',
        category: 'milestone',
        unlocked: true,
        unlockedAt: new Date(Date.now() - 15 * 24 * 60 * 60 * 1000).toISOString(),
        rewards: { xp: 500 },
      },
      {
        id: 'ach_50_articles',
        name: '创作达人',
        description: '累计完成50篇文章',
        icon: '🏆',
        category: 'milestone',
        unlocked: false,
        progress: 48,
        total: 50,
      },
      {
        id: 'ach_quality_90',
        name: '品质保证',
        description: '获得一篇质量分90分以上的文章',
        icon: '⭐',
        category: 'quality',
        unlocked: true,
        rewards: { xp: 300, badge: '品质作者' },
      },
      {
        id: 'ach_7_days_streak',
        name: '坚持不懈',
        description: '连续创作7天',
        icon: '🔥',
        category: 'efficiency',
        unlocked: true,
        progress: 7,
        total: 7,
        rewards: { xp: 400 },
      },
      {
        id: 'ach_30_days_streak',
        name: '创作大师',
        description: '连续创作30天',
        icon: '💎',
        category: 'efficiency',
        unlocked: false,
        progress: 7,
        total: 30,
      },
      {
        id: 'ach_all_models',
        name: '全能选手',
        description: '使用过所有AI模型',
        icon: '🤖',
        category: 'exploration',
        unlocked: false,
        progress: 3,
        total: 5,
      },
      {
        id: 'ach_shared_template',
        name: '乐于分享',
        description: '分享一个模板到社区',
        icon: '🎁',
        category: 'community',
        unlocked: false,
        progress: 0,
        total: 1,
      },
    ];
  }

  private getMockUserLevel(): UserLevel {
    return {
      level: 5,
      currentXP: 2350,
      nextLevelXP: 3000,
      totalXP: 8350,
      privileges: ['高级模板', '多模型对比', '数据导出', '优先支持'],
      title: '熟练作者',
    };
  }

  private getMockCalendarData(year: number, month?: number): CalendarData {
    const calendarData: CalendarData = {};
    const today = new Date();
    const startDate = month
      ? new Date(year, month - 1, 1)
      : new Date(year, 0, 1);
    const endDate = month
      ? new Date(year, month, 0)
      : new Date(year, 11, 31);

    for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
      if (d > today) break;

      const dateStr = d.toISOString().split('T')[0];
      // 60%的日期有创作记录
      if (Math.random() > 0.4) {
        calendarData[dateStr] = {
          wordCount: Math.floor(Math.random() * 3000) + 500,
          articleCount: Math.floor(Math.random() * 3) + 1,
          qualityScore: Math.floor(Math.random() * 20) + 75,
        };
      }
    }

    return calendarData;
  }

  private getMockRankings(type: RankingType): RankingsData {
    const rankings = Array.from({ length: 10 }, (_, i) => ({
      userId: `user_${i + 1}`,
      username: `用户${i + 1}`,
      avatar: `https://api.dicebear.com/7.x/avataaars/svg?seed=${i}`,
      value: type === 'quality'
        ? Math.floor(Math.random() * 20) + 80
        : Math.floor(Math.random() * 50000) + 10000,
      rank: i + 1,
    }));

    return {
      rankings,
      myRank: 15,
      total: 128,
    };
  }

  private getMockGoals(): CreationGoal[] {
    const today = new Date();
    const startOfWeek = new Date(today);
    startOfWeek.setDate(today.getDate() - today.getDay());
    const endOfWeek = new Date(startOfWeek);
    endOfWeek.setDate(startOfWeek.getDate() + 6);

    const startOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
    const endOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);

    return [
      {
        id: 'goal_daily_words',
        type: 'daily',
        target: 2000,
        current: 1500,
        metric: 'words',
        startDate: today.toISOString().split('T')[0],
        endDate: today.toISOString().split('T')[0],
        completed: false,
      },
      {
        id: 'goal_weekly_articles',
        type: 'weekly',
        target: 5,
        current: 3,
        metric: 'articles',
        startDate: startOfWeek.toISOString().split('T')[0],
        endDate: endOfWeek.toISOString().split('T')[0],
        completed: false,
      },
      {
        id: 'goal_monthly_quality',
        type: 'monthly',
        target: 85,
        current: 82,
        metric: 'quality',
        startDate: startOfMonth.toISOString().split('T')[0],
        endDate: endOfMonth.toISOString().split('T')[0],
        completed: false,
      },
    ];
  }

  private getMockStatisticsReport(timeRange: TimeRange): StatisticsReport {
    const statistics = this.getMockStatistics(timeRange);
    const today = new Date();
    const start = new Date(today);

    if (timeRange === 'week') {
      start.setDate(today.getDate() - 7);
    } else if (timeRange === 'month') {
      start.setMonth(today.getMonth() - 1);
    } else if (timeRange === 'today') {
      start.setHours(0, 0, 0, 0);
    } else {
      start.setFullYear(today.getFullYear() - 1);
    }

    return {
      period: {
        start: start.toISOString().split('T')[0],
        end: today.toISOString().split('T')[0],
      },
      summary: statistics,
      highlights: {
        bestArticle: {
          id: 'article_123',
          title: '人工智能在内容创作中的应用',
          score: 92,
        },
        mostProductiveDay: {
          date: new Date(today.getTime() - 3 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
          wordCount: 5200,
        },
        growthRate: 15.8,
      },
      achievements: this.getMockAchievements().filter(a => a.unlocked),
      recommendations: [
        '继续保持高质量创作，您的文章平均分已达到85分以上',
        '尝试使用更多AI模型进行对比，可以获得更优质的内容',
        '建议每天固定时间创作，形成良好的创作习惯',
        '可以将优质文章分享到社区，帮助其他创作者',
      ],
    };
  }

  private generateMockTrendData(days: number, min: number, max: number) {
    const trend = [];
    const today = new Date();

    for (let i = days - 1; i >= 0; i--) {
      const date = new Date(today);
      date.setDate(date.getDate() - i);
      trend.push({
        date: date.toISOString().split('T')[0],
        efficiency: Math.floor(Math.random() * (max - min)) + min,
      });
    }

    return trend;
  }
}

export const statisticsService = new StatisticsService();
